package com.malware.detection;


import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.List;
import java.util.Set;

import android.app.ActivityManager;
import android.app.ActivityManager.MemoryInfo;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Binder;
import android.os.IBinder;
import android.telephony.TelephonyManager;
import android.util.Log;

import android.widget.Toast;

public class SystemBehaviour extends Service {
	private Hashtable<String,Integer> afterCallResult;
	private final IBinder mBinder = new LocalBinder();
	private static final String TAG = "PoornimaMalware";
	private static final String ACTION = "android.intent.action.PHONE_STATE";
	public static List<String> suspectPermissionList = Arrays.asList("android.permission.RECORD_AUDIO");//,"android.permission.INTERNET","android.permission.READ_PHONE_STATE","android.permission.WRITE_EXTERNAL_STORAGE");  
	private Set<String> appsWithRecordPermission;
	private long memoryDuringCall;
	private long memoryAfterCall;
	private Hashtable<String,Integer> duringCallResult;
	Context context;
	private BroadcastReceiver callreceiver;
	CpuUsage cp;

	public class LocalBinder extends Binder {
		SystemBehaviour getService() {
			return SystemBehaviour.this;
		}
	}

	public IBinder onBind(Intent intent) {
		return mBinder;
	}

	//When you are in activity USE this function to get the result 
	public long get_mem_duringcall(){
		return memoryDuringCall;
	}

	//When you are in activity USE this function to get the result 
	public long get_mem_aftercall(){
		return memoryAfterCall;
	}


	//String path = "record";

	public void onCreate() {
		super.onCreate();

		Toast.makeText(this, "Recording Service Created", Toast.LENGTH_LONG).show();
		Log.d(TAG, "onCreate Service");
		appsWithRecordPermission = getAppPermissions();

		Log.d(TAG, "Inside the Service Create");
		final IntentFilter theFilter = new IntentFilter();
		theFilter.addAction(ACTION);

		this.callreceiver = new BroadcastReceiver() {

			@Override
			public void onReceive(Context context, Intent intent) {
				Log.d(TAG, "SystemBehaviour.... broadcast receiver!!!");
				String phone_state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);

				// Call is running
				if (phone_state.equals("OFFHOOK")) {
					Log.d(TAG, "Call started!!!");
					cp = new CpuUsage();
					duringCallResult= cp.findSuspiciousApps(appsWithRecordPermission);
					memoryDuringCall=getAvailableMemory();
					Intent broadcastIntent=new Intent("malwareDetection.intent");
					sendBroadcast(broadcastIntent);
				}

				//Call is done
				if (phone_state.equals("IDLE")) {
					Log.d(TAG, "Call ended!!!");
					CpuUsage cp=new CpuUsage();
					afterCallResult=cp.findSuspiciousApps(appsWithRecordPermission);
					memoryAfterCall=getAvailableMemory();
					Intent broadcastIntent=new Intent("malwareDetection.after.intent");
					sendBroadcast(broadcastIntent);
				}
			}
		};
		this.registerReceiver(this.callreceiver, theFilter);
	}

	public void onDestroy() {
		this.unregisterReceiver(this.callreceiver);
		Log.d(TAG, "Inside the Service Destroy");
	}

	//http://marcopkdev.wordpress.com/2011/08/19/android-sdk-how-to-retrieve-installed-application-list-and-permissions/
	public Set<String> getAppPermissions(){
		Set<String> suspectApps = new HashSet<String>();
		PackageManager pm = getPackageManager();
		// query the package manager and obtain the list of applications
		List<ApplicationInfo> packages = pm.getInstalledApplications(PackageManager.GET_META_DATA);
		for (ApplicationInfo applicationInfo : packages) {

			//It skips the system applications!!!
			if ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM)!=0)
				continue;
			try {
				PackageInfo packageInfo = pm.getPackageInfo(applicationInfo.packageName, PackageManager.GET_PERMISSIONS);

				//Get Permissions
				String[] requestedPermissions = packageInfo.requestedPermissions;
				if(requestedPermissions != null ){
					Set<String> permissionSet = new HashSet<String>(Arrays.asList(requestedPermissions));
					if(permissionSet != null)
					{
						if(permissionSet.containsAll(suspectPermissionList)){
							suspectApps.add(packageInfo.packageName);
						}
					}
				}else{
					continue;
				}
			}catch (NameNotFoundException e) {
				e.printStackTrace();
			}
		}
		return suspectApps;
	}



	//When you are in activity USE this function to get the result 
	public List<String> get_duringCall_result(){
		ArrayList<String> templist=new ArrayList<String>();
		if(duringCallResult!=null)
			for(String key:duringCallResult.keySet())
			{
				templist.add(key+"==>"+String.valueOf(duringCallResult.get(key)+"%"));
			}
		
		return templist;
	}



	//When you are in activity USE this function to get the result 
	public List<String> get_afterCall_result(){
		ArrayList<String> templist=new ArrayList<String>();
		if(afterCallResult.keySet()!=null)
			for(String key:afterCallResult.keySet())
			{
				templist.add(key+"==>"+String.valueOf(afterCallResult.get(key)+"%"));
			}
		return templist;
	}



	public long getAvailableMemory()
	{
		ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
		MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
		activityManager.getMemoryInfo(memoryInfo);
		Log.d(TAG,"MEMORY IS: "+String.valueOf( memoryInfo.availMem));
		return memoryInfo.availMem;
	}


}
